ARM DSP库CMSIS

您所在的位置:网站首页 keil stm32f4 ARM DSP库CMSIS

ARM DSP库CMSIS

2023-08-13 19:13| 来源: 网络整理| 查看: 265

之前用过STM32F10x比较多,做数字信号处理用过意法半导体官方的STM32F10x_DSP_Lib_V2.0.0,总觉得这个库不太好用:

1、数字滤波器FIR和IIR的函数只能对存在缓冲中的数组滤波,且没有能够保存滤波器中间状态的数据结构,导致再次调用这些滤波函数时需要一个新的稳定期,无法实现连续实时滤波。

2、只有定点FFT函数,输出结果保存在16bits的定点寄存器中,大大降低了FFT结果的动态范围。

因此我在STM32F10x上总习惯采用自己编写的C语言数字信号处理函数,无论是时间效率还是内存效率都差强人意。

最近在项目中开始使用带有浮点处理单元(FPU)的Cortex-M4核STM32F4,发现ARM公司自己提供的CMSIS(Cortex Microcontroller Software Interface Standard)中的数字信号库(CMSIS-DSP)确实要给力得多。下面以需要浮点能力的FFT功能为例,介绍CMSIS-DSP在MDK环境中的使用。

以下原创内容欢迎网友转载,但请注明出处: https://www.cnblogs.com/helesheng

一、准备工作和准备知识

1、在意法半导体官方网站下载包含CMSIS-DSP的外设库(https://www.st.com/en/embedded-software/stsw-stm32065.html),当然也可以到ARM官方的GitHub账号(https://github.com/ARM-software/CMSIS)下载所有ARM Cortex-M内核的DSP外设库。数字信号库包含在路径STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Libraries\CMSIS\DSP_Lib和STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Libraries\CMSIS\Lib下,将它们拷贝到目标工程文件夹下。其中Lib文件夹中包含的是经过不同编译器编译后能够运行在Cortex-M4内核上的底层数学库,DSP_Lib文件夹中包含的是调用底层函数封装而成的API函数源码。

2、Lib文件夹中包含的底层库包括:

arm_cortexM4lf_math.lib     arm_cortexM4bf_math.lib     arm_cortexM4l_math.lib     arm_cortexM4b_math.lib     arm_cortexM3l_math.lib     arm_cortexM3b_math.lib     arm_cortexM0l_math.lib     arm_cortexM0b_math.lib

M0、M3、M4分别代表Cortex-M0、Cortex-M3、Cortex-M4内核上运行的库;字母l代表小端地址格式,b代表大端地址格式(所有STM32皆为小端地址格式处理器);字母f代表使用浮点处理单元(FPU)进行计算的库。例如,我打算使用STM32F4处理器的FPU进行FFT运算,就需要将库文件arm_cortexM4lf_math.lib添加到Keil MDK工程中。

 

 3、DSP_Lib中包含了如下所示的多个文件夹,它们中的文件功能如下:1)BasicMathFunctions

基本数学函数:提供浮点数的各种基本运算函数,如向量加减乘除等运算。

2)CommonTables

数字信号处理常用参数表。

3)ComplexMathFunctions

复数计算数学函数。

4)ControllerFunctions

控制算法函数。包括正弦余弦,PID电机控制,矢量Clarke变换,矢量Clarke逆变换等。

5)FastMathFunctions

常见快速算法的数学函数。

6)FilteringFunctions

滤波函数功能,主要为FIR和LMS(最小均方根)等滤波函数。

7)MatrixFunctions

矩阵处理函数。包括矩阵加法、矩阵初始化、矩阵反、矩阵乘法、矩阵规模、矩阵减法、矩阵转置等函数。

8)StatisticsFunctions

统计功能函数。如求平均值、最大值、最小值、计算均方根RMS、计算方差/标准差等。

9)SupportFunctions

支持功能函数,如数据拷贝,Q格式和浮点格式相互转换,Q任意格式相互转换。

10)TransformFunctions

变换功能。包括复数FFT(CFFT)/复数FFT逆运算(CIFFT)、实数FFT(RFFT)/实数FFT逆运算(RIFFT)、和DCT(离散余弦变换)和配套的初始化函数。

例如,这里我打算通过浮点FFT运算进行频谱分析,就使用了TransformFunctions文件夹下的arm_cfft_f32.c中的函数。

 

二、配置Keil MDK工程

1、在Options的Target选项卡中使能浮点运算单元FPU。

图1

 2、在Options的C/C++选项卡的宏定义中添加如下数学计算可能用到的宏ARM_MATH_CM4,__CC_ARM,ARM_MATH_MATRIX_CHECK,ARM_MATH_ROUNDING。

图2

 三、调用DSP_LIB中的函数实现FFT

1、从ARM官方帮助文档中查找合适的函数及其使用方法

ARM官方的CMSIS-DSP库的帮助文档是HTML格式的网页,保存在.. \STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Libraries\CMSIS路径下,打开后如下图所示。

图3

我选择32位浮点(float)数据类型的函数arm_cfft_f32();来实现FFT,其原型如网页右侧视图所示。

从上面的网页中可以查得: 

1 void arm_cfft_f32 ( 2 const arm_cfft_instance_f32 * S, 3 float32_t * p1, 4 uint8_t ifftFlag, 5 uint8_t bitReverseFlag 6 );

函数名称中的字母“c”表明,这个函数的输入和输出都是复数(complex number)。输入复数向量存放在第二个参数p1指向的浮点数组中,函数执行完后输出复数向量亦存放在相同地址。输入输出复数数组的存储结构相同,偶数地址用于存储复数实部,随后的奇数地址用于存储同一个复数的虚部。

第一个参数则是一个指向复数浮点FFT常数结构体的指针,该结构体已经定义在头文件arm_const_structs.h中,可以直接通过&arm_cfft_sR_f32_len256、&arm_cfft_sR_f32_len512、&arm_cfft_sR_f32_len1024等形式应用,FFT变换的点数由改参数决定。

此处注意不要忘记在调用DSP库函数的文件之前添加头文件:#include "arm_const_structs.h"

第三个参数ifftFlag用于指定函数执行的FFT逆变换(ifftFlag=1),还是FFT正变换(ifftFlag=0)。第四个参数bitReverseFlag用于指定是否对结果进行位翻转变换,根据FFT理论知识可知,对自然顺序输入进行FFT蝶形运算的结果的顺序,是自然顺序输出的地址高低位翻转的结果。当bitReverseFlag=1时,该函数能够对输出的结果执行地址高低位翻转和顺序置换;当bitReverseFlag=0时,该功能被禁止。大多数情况下,为得到频率依次递增的频域数据,需要使能该函数的位翻转功能。

2、调用函数arm_cfft_f32();实现FFT

未验证STM32F4xx_DSP_StdPeriph_Lib中DSP功能调用的正确性,我对STM32F401RC片上ADC采集得到的信号进行了FFT变换和显示。具体实现步骤如下:

1)通过DMA控制ADC实现高速采样,代码如下(其中DMA配置函数ADC_Config();不是本文重点,具体代码此处未列出):

1 ADC_Config();//ADC和DMA配置 2 ADC_SoftwareStartConv(ADCx); //启动adc和DMA传输 3 while(DMA_GetFlagStatus(DMA_STREAMx, DMA_FLAG_TCIF0) == RESET) ; 4 //等待采样和DMA传输完成 5 ADC_DMACmd(ADCx, DISABLE); 6 DMA_ClearFlag(DMA_STREAMx, DMA_FLAG_TCIF0);

2)将采样结果放置在复数结构的缓冲区中。其中数组uhADCxConvertedValue[]中存放的A/D采样的结果是DMA控制器在此之前存入的,它们被放置到即将进行FFT的浮点数组fft_buf_float[ ]的偶数地址中。而奇数地址中存放的是FFT输入的虚部,这里被全部置0。

1 //FFT函数的输入和输出都是复数,因此还有虚部,将输入填入实部,虚部为0 2 for(i = 0; i


【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3